<!--
 * @LastEditors: 七七
 * @Date: 2023-01-10 22:20:24
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
</head>

<body>
  <script type="text/javascript">

    /*
     * 创建一个构造函数，专门用来创建Person对象的
     * 	构造函数就是一个普通的函数，创建方式和普通函数没有区别,
     * 	不同的是构造函数习惯上首字母大写
     * 
     * 构造函数和普通函数的区别就是调用方式的不同
     * 	普通函数是直接调用，而构造函数需要使用new关键字来调用
     * 
     * 构造函数的执行流程：
     * 	1.立刻创建一个新的对象
     * 	2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
     * 	3.逐行执行函数中的代码
     * 	4.将新建的对象作为返回值返回
     * 
     * 使用同一个构造函数创建的对象，我们称为一类对象，也将一个构造函数称为一个类。
     * 	我们将通过一个构造函数创建的对象，称为是该类的实例
     * 
     * this的情况：
     * 	1.当以函数的形式调用时，this是window
     * 	2.当以方法的形式调用时，谁调用方法this就是谁
     * 	3.当以构造函数的形式调用时，this就是新创建的那个对象
     * 
     */
    function Person(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
      this.sayName = function () {
        alert(this.name);
      };
    }

    function Dog() {

    }

    var per = new Person("孙悟空", 18, "男");
    var per2 = new Person("玉兔精", 16, "女");
    var per3 = new Person("奔波霸", 38, "男");

    var dog = new Dog();

    /*console.log(per);
    console.log(dog);*/

    /*
     * 使用instanceof可以检查一个对象是否是一个类的实例
     * 	语法：
     * 		对象 instanceof 构造函数
     * 如果是，则返回true，否则返回false
     */
    //console.log(per instanceof Person);
    //console.log(dog instanceof Person);

    /*
     * 所有的对象都是Object的后代，
     * 	所以任何对象和Object左instanceof检查时都会返回true
     */
    //console.log(dog instanceof Object);



    /*
     * 创建一个Person构造函数
     * 	- 在Person构造函数中，为每一个对象都添加了一个sayName方法，
     * 		目前我们的方法是在构造函数内部创建的，
     * 			也就是构造函数每执行一次就会创建一个新的sayName方法
     * 		也是所有实例的sayName都是唯一的。
     * 		这样就导致了构造函数执行一次就会创建一个新的方法，
     * 			执行10000次就会创建10000个新的方法，而10000个方法都是一摸一样的
     * 			这是完全没有必要，完全可以使所有的对象共享同一个方法
     */
    function Person(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
      //向对象中添加一个方法
      //this.sayName = fun;
    }

    //将sayName方法在全局作用域中定义
    /*
     * 将函数定义在全局作用域，污染了全局作用域的命名空间
     * 	而且定义在全局作用域中也很不安全
     */
    /*function fun(){
      alert("Hello大家好，我是:"+this.name);
    };*/
    //向原型中添加sayName方法
    Person.prototype.sayName = function () {
      alert("Hello大家好，我是:" + this.name);
    };

    //创建一个Person的实例
    var per = new Person("孙悟空", 18, "男");
    var per2 = new Person("猪八戒", 28, "男");
    per.sayName();
    per2.sayName();

			//console.log(per.sayName == per2.sayName);
  </script>
</body>

</html>